/**
 * Copyright (C)  Gadglet .
 *
 * This file is part of Gadglet
 *
 * Gadglet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Gadglet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Gadglet. If not, see <http://www.gnu.org/licenses/>.
 */

package com.gadglet.data;

import java.io.Serializable;
import java.util.Date;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.gadglet.core.RequestException;
import com.gadglet.data.utils.DomainUserStatus;
import com.gadglet.data.utils.PMF;
import com.gadglet.params.ReqErrorTypes;

/**
 * Persistence class for DomainUser
 * The class is used WITHOUT App Engine NameSpace, any access must handle 
 * existing request NameSpace
 *
 */


@PersistenceCapable
public class DomainUser implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7362642932236073325L;

	public DomainUser(String id, String account, String email, String nickName,
			int status, String timeZone, boolean domainAdmin, String openIdAuthDomain,String oAuthDomain, String openSocialViewerId, String oauthConsumerKey) {

		this.userId = id;
		this.accountId = account;
		this.email = email;
		this.nickName = nickName;
		this.creation = new Date();
		this.status = status;
		this.timeZone = timeZone;
		this.domainAdmin = domainAdmin;
		this.oAuthDomain = oAuthDomain;
		this.openIdAuthDomain =openIdAuthDomain;
		this.oauthConsumerKey = oauthConsumerKey;
		this.openSocialViewerId = openSocialViewerId;	
	}

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
	private String uniqueId;

	@Persistent
	private String userId;

	@Persistent
	private String accountId;

	// store user info
	@Persistent
	private String email;

	@Persistent
	private String nickName;

	@Persistent
	private Date creation;

	@Persistent
	private int status;

	@Persistent
	private String timeZone;

	@Persistent
	private boolean domainAdmin;
	
	@Persistent
	private String oAuthDomain;

	@Persistent
	private String openIdAuthDomain;
	
	@Persistent
	private String oauthConsumerKey;
	
	@Persistent
	private String 	openSocialViewerId;
	
	@Persistent
	private String photoUrl; 


	@Persistent
	private String title;
	
	
	
	public String getUniqueId() {
		return uniqueId;
	}
	
	
	public String getPhotoUrl() {
		return photoUrl;
	}

	public void setPhotoUrl(String photoUrl) {
		this.photoUrl = photoUrl;
	}
	

	
	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}
	
	
		
	public String getOauthConsumerKey() {
		return this.oauthConsumerKey;
	}

	public String getOpensocialViewerId() {
		return openSocialViewerId;
	}

	public void setOpensocialViewerId(String openSocialViewerId) {
		this.openSocialViewerId = openSocialViewerId;
	}

	public String getAuthDomain() {
		return oAuthDomain;
	}
	
	public boolean isDomainAdmin() {
		return domainAdmin;
	}

	public String getId() {
		return userId;
	}

	public String getAccount() {
		return accountId;
	}

	Date getCreation() {
		return creation;
	}

	
	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}

	public String getTimeZone() {
		return timeZone;
	}

	public void setTimeZone(String timeZone) {
		this.timeZone = timeZone;
	}

	public String getEmail() {
		return email;
	}

	public String getNickName() {
		return nickName;
	}
	
	public void  setNickName(String name) {
		 nickName=name;
	}
	

	public boolean save() throws Exception {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.currentTransaction().begin();
		
		boolean done = false;
		try {
			pm.makePersistent(this);
			pm.currentTransaction().commit();
			done = true;
		} catch (Exception e) {
			throw e;
		} finally {
			if (pm.currentTransaction().isActive())
		        pm.currentTransaction().rollback();
			pm.close();
		}
		return done;
	}

	public void changeStatus(DomainUserStatus status) throws Exception {
		// add security checks ...
		
		DomainAccount domainAccount = DomainAccountUtils.getDomainAccountByID(getAccount());
		
		if(!DomainUserUtils.isCurrentUserDomainAdmin() && !domainAccount.isAllowUsersSelfActivation())
			throw new RequestException (ReqErrorTypes.UNAUTHORIZED_OPERATION);
			
		if(	domainAccount.getDomainActiveUsersNum()>=domainAccount.getMaxUsers())
			throw new RequestException (ReqErrorTypes.DOMAIN_ACCOUNT_EXCEED_USERS_QUATA);
		
		setStatus(status.getUserStatus());
		try {
			save();
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * Set the user to be DomainAccount Admin user
	 * @throws Exception
	 */
	public void setAdmin() throws Exception {

		if (DomainUserUtils.isCurrentUserDomainAdmin()) 
			throw new RequestException (ReqErrorTypes.UNAUTHORIZED_OPERATION);
			
		this.domainAdmin = true;

		try {
			save();
		} catch (Exception e) {
			throw e;
		}
		
	}

	/**
	 * Disable Admin user
	 * @throws Exception
	 */
	public void disableAdmin() throws Exception {

		if (DomainUserUtils.isCurrentUserDomainAdmin()) 
			throw new RequestException (ReqErrorTypes.UNAUTHORIZED_OPERATION);
		
		this.domainAdmin = false;

		try {
			save();
		} catch (Exception e) {
			throw e;
		}
	}

}
